﻿using Newtonsoft.Json.Serialization;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace QbservableHubTests
{
    /// <summary>
    /// Used to set type convention
    /// </summary>
    public class CustomSerializationBinder : DefaultSerializationBinder
    {
        #region BindToName

        /// <summary>
        /// When overridden in a derived class, controls the 
        /// binding of a serialized object to a type (Type -> Assembly Name + Type Name convention).
        /// </summary>
        /// <param name="serializedType">The type of the object the formatter creates a new instance of.</param>
        /// <param name="assemblyName">Specifies the <see cref="T:System.Reflection.Assembly" /> name of the serialized object.</param>
        /// <param name="typeName">Specifies the <see cref="T:System.Type" /> name of the serialized object.</param>
        public override void BindToName(
            Type serializedType,
            out string assemblyName,
            out string typeName)
        {
            base.BindToName(serializedType,
                out assemblyName,
                out typeName);

            if (assemblyName == "QbservableCore.Serialization, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null")
            {
                switch (typeName)
                {
                    case "QbservableCore.Serialization.MethodCallNode":
                        assemblyName = string.Empty;
                        typeName = "MethodCallNode";
                        break;
                    case "QbservableCore.Serialization.ExpRepresentationBase[]":
                        assemblyName = string.Empty;
                        typeName = "ExpRepBase[]";
                        break;
                }
            }
            else if (assemblyName == "mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")
            {
                switch (typeName)
                {
                    case "System.Int32":
                        assemblyName = string.Empty;
                        typeName = "I4";
                        break;
                    case "System.Int64":
                        assemblyName = string.Empty;
                        typeName = "I8";
                        break;
                }
            }
        }

        #endregion // BindToName

        #region BindToType

        /// <summary>
        /// When overridden in a derived class, controls the 
        /// binding of a serialized object to a type  (Assembly Name + Type Name -> Type).
        /// </summary>
        /// <param name="assemblyName">Specifies the <see cref="T:System.Reflection.Assembly" /> name of the serialized object.</param>
        /// <param name="typeName">Specifies the <see cref="T:System.Type" /> name of the serialized object.</param>
        /// <returns>
        /// The type of the object the formatter creates a new instance of.
        /// </returns>
        public override Type BindToType(string assemblyName, string typeName)
        {
            if (assemblyName == string.Empty)
            {
                switch (typeName)
                {
                    case "MethodCallNode":
                        typeName = "QbservableCore.Serialization.MethodCallNode";
                        assemblyName = "QbservableCore.Serialization, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null";
                        break;
                    case "ExpRepBase[]":
                        typeName = "QbservableCore.Serialization.ExpRepresentationBase[]";
                        assemblyName = "QbservableCore.Serialization, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null";
                        break;
                    case "I4":
                        assemblyName = "mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089";
                        typeName = "System.Int32";
                        break;
                    case "I8":
                        assemblyName = "mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089";
                        typeName = "System.Int64";
                        break;
                }
            }

            var t = base.BindToType(assemblyName, typeName);
            return t;
        }

        #endregion // BindToType
    }
}
